package com.roc.admin.infrastructure.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.roc.admin.domain.entity.Role;
import com.roc.admin.domain.repository.RoleRepository;
import com.roc.admin.infrastructure.mapper.RoleMapper;
import com.roc.admin.infrastructure.persistence.RolePO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 角色仓储实现类
 */
@Repository
public class RoleRepositoryImpl implements RoleRepository {

    private final RoleMapper roleMapper;

    public RoleRepositoryImpl(RoleMapper roleMapper) {
        this.roleMapper = roleMapper;
    }

    @Override
    public Role save(Role role) {
        RolePO rolePO = toRolePO(role);
        if (rolePO.getId() == null) {
            roleMapper.insert(rolePO);
        } else {
            roleMapper.updateById(rolePO);
        }
        return toRole(rolePO);
    }

    @Override
    public Optional<Role> findById(Long id) {
        RolePO rolePO = roleMapper.selectById(id);
        return Optional.ofNullable(rolePO).map(this::toRole);
    }

    @Override
    public Optional<Role> findByCode(String code) {
        LambdaQueryWrapper<RolePO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RolePO::getCode, code);
        RolePO rolePO = roleMapper.selectOne(queryWrapper);
        return Optional.ofNullable(rolePO).map(this::toRole);
    }

    @Override
    public List<Role> findAll() {
        List<RolePO> rolePOList = roleMapper.selectList(null);
        return rolePOList.stream().map(this::toRole).collect(Collectors.toList());
    }

    @Override
    public List<Role> findByUserId(Long userId) {
        List<Long> roleIds = roleMapper.selectRoleIdsByUserId(userId);
        if (roleIds.isEmpty()) {
            return List.of();
        }
        LambdaQueryWrapper<RolePO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(RolePO::getId, roleIds);
        List<RolePO> rolePOList = roleMapper.selectList(queryWrapper);
        return rolePOList.stream().map(this::toRole).collect(Collectors.toList());
    }

    @Override
    public void deleteById(Long id) {
        roleMapper.deleteById(id);
    }

    @Override
    public boolean existsByCode(String code) {
        LambdaQueryWrapper<RolePO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RolePO::getCode, code);
        return roleMapper.selectCount(queryWrapper) > 0;
    }

    /**
     * 将角色实体转换为持久化对象
     *
     * @param role 角色实体
     * @return 角色持久化对象
     */
    private RolePO toRolePO(Role role) {
        if (role == null) {
            return null;
        }
        RolePO rolePO = new RolePO();
        BeanUtils.copyProperties(role, rolePO);
        return rolePO;
    }

    /**
     * 将持久化对象转换为角色实体
     *
     * @param rolePO 角色持久化对象
     * @return 角色实体
     */
    private Role toRole(RolePO rolePO) {
        if (rolePO == null) {
            return null;
        }
        Role role = new Role();
        BeanUtils.copyProperties(rolePO, role);
        return role;
    }
}
